#ifndef _LIST_SELF
#define _LIST_SELF

#include "Node.h"


template<class T>
class List_self
{
public:
	List_self();
	List_self(const List_self<T>& L);
	~List_self();

	void printf();
	bool isEmpty() const { return (front == rear) ? true : false; }
	bool isEnd() const { return (currPtr == NULL) ? true : false; }

	void reset(int pos = 0);
	void movestep();

	void insertFront(const T& item);
	void insertRear(const T& item);
	void insertAfter(const T& item);

	void deletecurrent();
	

private:
	Node<T>* front, *rear;
	Node<T>* prevPtr, *currPtr;
	int size;
	int Pos;
	Node<T>* newNode(const T& item, Node<T>* ptr = NULL);
	void copy(const List_self<T>& L);
	void clear();

};

template<class T>
List_self<T>::List_self()
	:size(0), Pos(0)
{
	rear = front = new Node<T>();
	prevPtr = currPtr = front;
}

template<class T>
List_self<T>::~List_self()
{
	clear();
	delete front;
}

template<class T>
List_self<T>::List_self(const List_self<T>& L)
{
	rear = front = new Node<T>();
	prevPtr = currPtr = front;
	Pos = L.Pos;
	copy(L);
}

template<class T>
void List_self<T>::printf()
{
	reset(1);
	while (!isEnd())
	{
		cout << currPtr->data << "  ";
		movestep();
	}
	cout << endl;
}
template<class T>
void List_self<T>::insertFront(const T& item)
{
	prevPtr = front;
	currPtr = newNode(item, front->next);
	front->next = currPtr;

	if (isEmpty()) rear = currPtr;

	size++;
}
template<class T>
void List_self<T>::insertRear(const T& item)
{
	prevPtr = rear;
	currPtr = newNode(item);
	rear->next = currPtr;
	rear = currPtr;

	size++;
}

template<class T>
void List_self<T>::insertAfter(const T& item)
{
	if (isEnd()) insertRear(item);
	prevPtr = currPtr;
	currPtr = newNode(item, currPtr->next);
	prevPtr->next = currPtr;
	size++;
}

template<class T>
void List_self<T>::deletecurrent()
{
	if (isEmpty() || (front == currPtr) || isEnd()) return;
	if (currPtr == rear)
	{
		prevPtr->next = NULL;
		delete rear;
		rear = currPtr = prevPtr;
		size--;
		return;
	}
	prevPtr->next = currPtr->next;
	delete currPtr;
	currPtr = prevPtr;
	size--;

}

template<class T>
void List_self<T>::reset(int pos)
{
	currPtr = prevPtr = front;
	this->Pos = pos;
	for (int i = 0; i < pos; i++)
	{
		movestep();
	}
}

template<class T>
void List_self<T>::movestep()
{
	prevPtr = currPtr;
	currPtr = currPtr->next;
}

template<class T>
Node<T>* List_self<T>::newNode(const T& item, Node<T>* ptr)
{
	Node<T>* temp = new Node<T>(item, ptr);
	return temp;
}

template<class T>
void List_self<T>::clear()
{
	if (isEmpty()) return;
	reset(1);
	while (!isEnd())
	{
		movestep();
		delete prevPtr;
		size--;
	}
	prevPtr = currPtr = rear = front;
}

template<class T>
void List_self<T>::copy(const List_self<T>& L)
{
	List_self<T>& L1 = const_cast<List_self<T>&>(L);
	L1.reset(1);
	for (int i = 0; i < L1.size; i++)
	{
		insertRear(L.currPtr->data);
		L1.movestep();
	}
}



#endif // !_LIST_SELF

